/*
 *@param thread:		pthread_t 类型指针，当 pthread_create()成功返回时，
						新创建的线程的线程 ID 会保存在参数 thread所指向的内存中，
						后续的线程相关函数会使用该标识来引用此线程。
 *@param attr:			pthread_attr_t 类型指针，指向 pthread_attr_t 类型的缓冲区， 
						pthread_attr_t 数据类型定义了线程的各种属性，如果将参数 attr 设置为 NULL， 
						那么表示将线程的所有属性设置为默认值，以此创建新线程。
 *@param start_routine: 参数 start_routine 是一个函数指针，指向一个函数， 新创建的线程从 start_routine()函数开始运行，
						该函数返回值类型为void *，并且该函数的参数只有一个void *，其实这个参数就是pthread_create()函数的第四个参数 arg。
						如果需要向 start_routine()传递的参数有一个以上，那么需要把这些参数放到一个结构体中，然后把这个结构体对象的地址作为 arg 参数传入。
 *@param arg:			传递给start_routine()函数的参数。一般情况下，需要将 arg 指向一个全局或堆变量，
						意思就是说在线程的生命周期中，该 arg 指向的对象必须存在，否则如果线程中访问了该对象将会出现错误。 
						然也可将参数 arg 设置为 NULL，表示不需要传入参数给 start_routine()函数。
 *@return 				成功返回 0；失败时将返回一个错误号，并且参数 thread 指向的内容是不确定的。
*/
//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>

//测试新进程id与函数得到id是否匹配
pthread_t tid;

static void *new_thread_start(void *arg)
{
	printf("新线程：进程ID<%d> 全局线程ID<%lu>  函数线程ID<%lu>\n", getpid(), tid,pthread_self());
	return (void*)0;  //执行 return 语句终止线程
}

int main(void)
{
	int ret;

	ret = pthread_create(&tid, NULL, new_thread_start, NULL);
	if (ret)
	{
		//在标准 I/O 中，可以使用 stdin、 stdout、 stderr 来表示标准输入、标准输出和标准错误。
		//fprintf()可将格式化数据写入到由 FILE 指针指定的文件中，譬如将字符串“Hello World”写入到标准错误：
		fprintf(stderr,"pthread_create error:%s\n",strerror(ret));
		exit(-1);
	}

	printf("主线程：进程ID<%d> 线程ID<%lu>\n", getpid(), pthread_self());
	sleep(1);
	//延时，new_thread_start线程函数执行完等待一会，如果进程中的任意线程调用 exit()、 _exit()或者_Exit()，那么将会导致整个进程终止，这里需要注意！这里的延时也不会执行       
	exit(0);
}